package cn.uyunsky.platform.servlet;

import cn.uyunsky.platform.BeanFactoryUtil;
import cn.uyunsky.platform.config.ConfigFactory;
import cn.uyunsky.platform.config.bean.page.PageBean;
import cn.uyunsky.platform.config.reader.PageDefineReader;
import cn.uyunsky.platform.data.UData;
import cn.uyunsky.platform.data.UHead;
import cn.uyunsky.platform.exception.PLException;
import cn.uyunsky.platform.service.ServiceExecute;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.util.WebUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

/**
 * Servlet implementation class PageDispacth
 */
public class PageDispacth extends HttpServlet {
    private static Log log = LogFactory.getLog(PageDispacth.class);


    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public PageDispacth() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        long start = System.currentTimeMillis();

        String uri = request.getRequestURI();
        String pagecode = uri.substring(uri.lastIndexOf("/") + 1, uri.indexOf("."));
        log.info("跳转到页面:[" + pagecode + "]");
        try {
            //获取page_define.xml配置
            ConfigFactory configFactory = (ConfigFactory) BeanFactoryUtil.getBean("configFactory");
            PageDefineReader reader = (PageDefineReader) configFactory.getReader(PageDefineReader.class);
            PageBean bean = reader.getPageBean(pagecode);
            if (bean == null) {
                log.error("页面码[" + pagecode + "]未定义!!!");
                throw new Exception("页面码[" + pagecode + "]未定义,无法跳转页面");
            }

            String service = bean.getService();
            if (StringUtils.isNotBlank(service)) {
                //获取页面请求数据
                UData data = getRequestData(request, service);
                if (log.isDebugEnabled())
                    log.debug("原始请求数据:" + data);

                ServiceExecute execute = (ServiceExecute) BeanFactoryUtil.getBean("serviceExecute");
                //执行服务
                UData resData = execute.execute(service, data);

                if (!resData.getHead().isSuccess()) {
                    throw new PLException(resData.getHead().getErrorcode(), resData.getHead().getMsg());
                }
                Map<String, Object> resBody = resData.getBody();
                if (resBody != null) {
                    //将执行结果置入request中
                    for (Iterator<Map.Entry<String, Object>> iterator = resBody.entrySet().iterator(); iterator.hasNext(); ) {
                        Map.Entry<String, Object> entry = iterator.next();
                        //将服务执行结果体数据置入request attribute中
                        request.setAttribute(entry.getKey(), entry.getValue());
                    }
                }
            }


            log.info("跳转到页面:" + bean.getUri());
            request.getRequestDispatcher(bean.getUri()).forward(request, response);
        } catch (Exception e) {//还需要设置一个统一异常
            log.error("page dispacth 执行异常!", e);
            //出现异常将进入error.jsp
            throw new ServletException("系统异常!", e);
        }
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        throw new RuntimeException("页面跳转不支持post方式");
    }

    /**
     * <p>Description: 从request中获取数据,组装成UData;因为这里只处理URL页面初始化,因此用map来表示请求的url参数</p>
     * 参数说明:
     *
     * @param request
     * @param pageCode
     * @return
     */
    public static UData getRequestData(HttpServletRequest request, String pageCode) {
        UData requestdata = new UData();

		/* 获取头数据 */
        UHead head = new UHead();
        head.setService(pageCode);
        head.setContextData(ServletUtil.getSessionData(request));
        //TODO 其他USER信息

        requestdata.setHead(head);

        Map body = WebUtils.getParametersStartingWith(request, "");
        requestdata.setBody(body);

        //此种方式无请求JSON
        return requestdata;
    }

}
